{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-10-31T07:56:44.802318Z",
     "start_time": "2025-10-31T07:56:42.301041Z"
    }
   },
   "source": [
    "from json_utils import extract_nothink_json\n",
    "from typing import Dict, List\n",
    "from datetime import datetime\n",
    "import json\n",
    "import re\n",
    "\n",
    "from langchain_ollama import OllamaLLM\n",
    "from langgraph.graph import StateGraph, END\n",
    "\n",
    "try:\n",
    "    from juputer_constants import OLLAMA_DEFAULT_MODEL\n",
    "\n",
    "    ollama = OllamaLLM(model=OLLAMA_DEFAULT_MODEL)\n",
    "except ImportError:\n",
    "    # 如果没有定义常量文件，使用默认模型\n",
    "    ollama = OllamaLLM(model=\"llama3\")\n",
    "\n",
    "\n",
    "class AgentState(dict):\n",
    "    input: str\n",
    "    output: str = \"\"\n",
    "    tool_result: str = \"\"\n",
    "    tool_calls: list = []  # 存储按顺序排列的工具调用列表\n",
    "    tool_results: dict = {}  # 存储各个工具的结果\n",
    "    current_tool_index: int = 0  # 当前需要调用的工具索引\n",
    "\n",
    "\n",
    "workflow = StateGraph(AgentState)\n",
    "\n",
    "\n",
    "def agent_node(state: AgentState) -> Dict:\n",
    "    # 定义可用工具\n",
    "    tools = [\n",
    "        {\"name\": \"get_current_time\", \"description\": \"获取当前时间\"},\n",
    "        {\"name\": \"get_weather\", \"description\": \"获取天气信息\"}\n",
    "    ]\n",
    "\n",
    "    # 构建工具描述\n",
    "    tools_description = \"\\n\".join([f\"- {tool['name']}: {tool['description']}\" for tool in tools])\n",
    "\n",
    "    prompt = f\"\"\"你是一个智能代理，可以根据用户请求决定是否需要调用工具。\n",
    "\n",
    "可用工具列表:\n",
    "{tools_description}\n",
    "\n",
    "用户请求: {state['input']}\n",
    "\n",
    "请分析用户请求，判断需要调用哪些工具以及调用顺序。\n",
    "你必须严格按照以下格式回复，不要添加任何其他文字:\n",
    "\n",
    "如果需要调用工具，请回复:\n",
    "{{\"action\": \"tool_call\", \"tool_calls\": [{{\"name\": \"工具名称1\", \"order\": 1}}, {{\"name\": \"工具名称2\", \"order\": 2}}]}}\n",
    "\n",
    "如果不需要调用工具，请回复:\n",
    "{{\"action\": \"finish\"}}\n",
    "\n",
    "注意：\n",
    "1. order字段表示调用顺序，数字越小优先级越高\n",
    "2. 可以多次调用同一个工具\n",
    "\n",
    "示例:\n",
    "{{\"action\": \"tool_call\", \"tool_calls\": [{{\"name\": \"get_current_time\", \"order\": 1}}, {{\"name\": \"get_weather\", \"order\": 2}}]}}\n",
    "或者\n",
    "{{\"action\": \"finish\"}}\n",
    "/nothink\"\"\"\n",
    "\n",
    "    decision = ollama.invoke(prompt)\n",
    "    print(f\"LLM决策结果: {decision}\")\n",
    "\n",
    "    # 尝试解析JSON\n",
    "    try:\n",
    "        decision_json = json.loads(extract_nothink_json(decision))\n",
    "        print(f\"解析到的JSON: {decision_json}\")\n",
    "        action = decision_json.get(\"action\", \"finish\")\n",
    "        tool_calls = decision_json.get(\"tool_calls\", []) if action == \"tool_call\" else []\n",
    "\n",
    "        # 按照order字段排序\n",
    "        tool_calls.sort(key=lambda x: x.get(\"order\", 999))\n",
    "        return {\"output\": action, \"tool_calls\": tool_calls, \"current_tool_index\": 0}\n",
    "    except json.JSONDecodeError:\n",
    "        print(\"[ERROR] 解析JSON失败，暂停调用。\")\n",
    "        return {\"output\": \"finish\", \"tool_calls\": [], \"current_tool_index\": 0}\n",
    "\n",
    "\n",
    "def time_tool_node(state: AgentState) -> Dict:\n",
    "    print(\"=== 调用时间工具 ===\")\n",
    "    current_time = datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n",
    "    result = f\"当前时间: {current_time}\"\n",
    "    print(f\"时间工具返回: {result}\")\n",
    "    # 返回结果时保留其他状态\n",
    "    tool_results = state.get(\"tool_results\", {}).copy()\n",
    "    tool_results[\"get_current_time\"] = result\n",
    "    return {\"tool_results\": tool_results, \"current_tool_index\": state.get(\"current_tool_index\", 0) + 1}\n",
    "\n",
    "\n",
    "def weather_tool_node(state: AgentState) -> Dict:\n",
    "    print(\"=== 调用天气工具 ===\")\n",
    "    # 模拟天气信息\n",
    "    result = \"当前天气: 晴朗，温度 25°C，湿度 60%\"\n",
    "    print(f\"天气工具返回: {result}\")\n",
    "    # 返回结果时保留其他状态\n",
    "    tool_results = state.get(\"tool_results\", {}).copy()\n",
    "    tool_results[\"get_weather\"] = result\n",
    "    return {\"tool_results\": tool_results, \"current_tool_index\": state.get(\"current_tool_index\", 0) + 1}\n",
    "\n",
    "\n",
    "def decide_next_node(state: AgentState):\n",
    "    output = state[\"output\"]\n",
    "    print(f\"决策函数接收到的输出: {output}\")\n",
    "\n",
    "    if output == \"tool_call\" and state[\"tool_calls\"]:\n",
    "        # 获取需要调用的工具列表\n",
    "        tool_calls = state[\"tool_calls\"]\n",
    "        current_index = state.get(\"current_tool_index\", 0)\n",
    "\n",
    "        # 检查是否有下一个工具需要调用\n",
    "        if current_index < len(tool_calls):\n",
    "            next_tool = tool_calls[current_index][\"name\"]\n",
    "            if next_tool == \"get_current_time\":\n",
    "                print(\"-> 路由到时间工具节点\")\n",
    "                return \"time_tool\"\n",
    "            elif next_tool == \"get_weather\":\n",
    "                print(\"-> 路由到天气工具节点\")\n",
    "                return \"weather_tool\"\n",
    "\n",
    "    print(\"-> 路由到结束节点\")\n",
    "    return END\n",
    "\n",
    "\n",
    "def tool_completion_router(state: AgentState):\n",
    "    \"\"\"工具调用完成后的路由器\"\"\"\n",
    "    tool_calls = state.get(\"tool_calls\", [])\n",
    "    current_index = state.get(\"current_tool_index\", 0)\n",
    "    tool_results = state.get(\"tool_results\", {})\n",
    "\n",
    "    print(f\"工具调用序列: {[tc['name'] for tc in tool_calls]}\")\n",
    "    print(f\"当前索引: {current_index}\")\n",
    "    print(f\"已完成的工具调用: {list(tool_results.keys())}\")\n",
    "\n",
    "    # 检查是否还有未调用的工具\n",
    "    if current_index < len(tool_calls):\n",
    "        next_tool = tool_calls[current_index][\"name\"]\n",
    "        print(f\"准备调用下一个工具: {next_tool}\")\n",
    "\n",
    "        # 根据工具名称决定路由\n",
    "        if next_tool == \"get_current_time\":\n",
    "            print(\"-> 路由到时间工具节点\")\n",
    "            return \"time_tool\"\n",
    "        elif next_tool == \"get_weather\":\n",
    "            print(\"-> 路由到天气工具节点\")\n",
    "            return \"weather_tool\"\n",
    "\n",
    "    # 如果所有工具都调用完毕，进入结果聚合\n",
    "    print(\"-> 所有工具调用完毕，进入结果聚合\")\n",
    "    return \"aggregate_results\"\n",
    "\n",
    "\n",
    "def aggregate_results_node(state: AgentState) -> Dict:\n",
    "    print(\"=== 聚合工具调用结果 ===\")\n",
    "    tool_results = state.get(\"tool_results\", {})\n",
    "    tool_calls = state.get(\"tool_calls\", [])\n",
    "\n",
    "    # 按照调用顺序构建综合结果\n",
    "    result_parts = []\n",
    "    for tool_call in tool_calls:\n",
    "        tool_name = tool_call[\"name\"]\n",
    "        if tool_name in tool_results:\n",
    "            result_parts.append(tool_results[tool_name])\n",
    "\n",
    "    aggregated_result = \"\\n\".join(result_parts)\n",
    "    print(f\"聚合结果: {aggregated_result}\")\n",
    "\n",
    "    return {\"tool_result\": aggregated_result}\n",
    "\n",
    "\n",
    "def final_response_node(state: AgentState) -> Dict:\n",
    "    print(\"=== 生成最终响应 ===\")\n",
    "    # 结合原始输入和工具结果生成最终响应\n",
    "    if state[\"tool_result\"]:\n",
    "        final_response = f\"根据您的请求'{state['input']}'，查询结果如下:\\n{state['tool_result']}\"\n",
    "    else:\n",
    "        final_response = f\"已处理您的请求: {state['input']}\"\n",
    "\n",
    "    print(f\"最终响应: {final_response}\")\n",
    "    return {\"output\": \"completed\", \"tool_result\": final_response}\n",
    "\n",
    "\n",
    "workflow.add_node(\"agent\", agent_node)\n",
    "workflow.add_node(\"time_tool\", time_tool_node)\n",
    "workflow.add_node(\"weather_tool\", weather_tool_node)\n",
    "workflow.add_node(\"aggregate_results\", aggregate_results_node)\n",
    "workflow.add_node(\"final_response\", final_response_node)\n",
    "\n",
    "workflow.set_entry_point(\"agent\")\n",
    "\n",
    "# 添加条件边\n",
    "workflow.add_conditional_edges(\n",
    "    \"agent\",\n",
    "    decide_next_node,\n",
    "    {\n",
    "        \"time_tool\": \"time_tool\",\n",
    "        \"weather_tool\": \"weather_tool\",\n",
    "        END: END\n",
    "    }\n",
    ")\n",
    "\n",
    "# 添加工具完成路由器\n",
    "workflow.add_conditional_edges(\n",
    "    \"time_tool\",\n",
    "    tool_completion_router,\n",
    "    {\n",
    "        \"time_tool\": \"time_tool\",\n",
    "        \"weather_tool\": \"weather_tool\",\n",
    "        \"aggregate_results\": \"aggregate_results\"\n",
    "    }\n",
    ")\n",
    "\n",
    "workflow.add_conditional_edges(\n",
    "    \"weather_tool\",\n",
    "    tool_completion_router,\n",
    "    {\n",
    "        \"time_tool\": \"time_tool\",\n",
    "        \"weather_tool\": \"weather_tool\",\n",
    "        \"aggregate_results\": \"aggregate_results\"\n",
    "    }\n",
    ")\n",
    "\n",
    "workflow.add_edge(\"aggregate_results\", \"final_response\")\n",
    "workflow.add_edge(\"final_response\", END)\n",
    "\n",
    "app = workflow.compile()"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\"action\": \"tool_call\", \"tool_calls\": [{\"name\": \"get_current_time\", \"order\": 1}]}\n"
     ]
    }
   ],
   "execution_count": 58
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-31T07:56:45.800139Z",
     "start_time": "2025-10-31T07:56:44.810318Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from IPython.display import Image, display\n",
    "\n",
    "try:\n",
    "    display(Image(app.get_graph().draw_mermaid_png(max_retries=5)))\n",
    "except:\n",
    "    print(\"无法显示流程图\")"
   ],
   "id": "1d7a7f16ea727261",
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 59
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-31T07:56:58.841477Z",
     "start_time": "2025-10-31T07:56:45.817138Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 测试时间工具\n",
    "print(\"=== 测试时间工具 ===\")\n",
    "input_data = {\"input\": \"现在几点了?\"}\n",
    "print(f\"输入: {input_data['input']}\")\n",
    "result = app.invoke(input_data)\n",
    "print(f\"结果: {result['tool_result']}\\n\")"
   ],
   "id": "3bfdf32c228a8cd1",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "=== 测试时间工具 ===\n",
      "输入: 现在几点了?\n",
      "LLM决策结果: <think>\n",
      "\n",
      "</think>\n",
      "\n",
      "{\"action\": \"tool_call\", \"tool_calls\": [{\"name\": \"get_current_time\", \"order\": 1}]}\n",
      "解析到的JSON: {'action': 'tool_call', 'tool_calls': [{'name': 'get_current_time', 'order': 1}]}\n",
      "决策函数接收到的输出: tool_call\n",
      "-> 路由到时间工具节点\n",
      "=== 调用时间工具 ===\n",
      "时间工具返回: 当前时间: 2025-10-31 15:56:58\n",
      "工具调用序列: ['get_current_time']\n",
      "当前索引: 1\n",
      "已完成的工具调用: ['get_current_time']\n",
      "-> 所有工具调用完毕，进入结果聚合\n",
      "=== 聚合工具调用结果 ===\n",
      "聚合结果: 当前时间: 2025-10-31 15:56:58\n",
      "=== 生成最终响应 ===\n",
      "最终响应: 根据您的请求'现在几点了?'，查询结果如下:\n",
      "当前时间: 2025-10-31 15:56:58\n",
      "结果: 根据您的请求'现在几点了?'，查询结果如下:\n",
      "当前时间: 2025-10-31 15:56:58\n",
      "\n"
     ]
    }
   ],
   "execution_count": 60
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-31T07:57:11.956576Z",
     "start_time": "2025-10-31T07:56:58.849472Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 测试天气工具\n",
    "print(\"=== 测试天气工具 ===\")\n",
    "input_data = {\"input\": \"今天天气怎么样?\"}\n",
    "print(f\"输入: {input_data['input']}\")\n",
    "result = app.invoke(input_data)\n",
    "print(f\"结果: {result['tool_result']}\\n\")"
   ],
   "id": "1fde9e299a691879",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "=== 测试天气工具 ===\n",
      "输入: 今天天气怎么样?\n",
      "LLM决策结果: <think>\n",
      "\n",
      "</think>\n",
      "\n",
      "{\"action\": \"tool_call\", \"tool_calls\": [{\"name\": \"get_weather\", \"order\": 1}]}\n",
      "解析到的JSON: {'action': 'tool_call', 'tool_calls': [{'name': 'get_weather', 'order': 1}]}\n",
      "决策函数接收到的输出: tool_call\n",
      "-> 路由到天气工具节点\n",
      "=== 调用天气工具 ===\n",
      "天气工具返回: 当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "工具调用序列: ['get_weather']\n",
      "当前索引: 1\n",
      "已完成的工具调用: ['get_weather']\n",
      "-> 所有工具调用完毕，进入结果聚合\n",
      "=== 聚合工具调用结果 ===\n",
      "聚合结果: 当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "=== 生成最终响应 ===\n",
      "最终响应: 根据您的请求'今天天气怎么样?'，查询结果如下:\n",
      "当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "结果: 根据您的请求'今天天气怎么样?'，查询结果如下:\n",
      "当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "\n"
     ]
    }
   ],
   "execution_count": 61
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-31T07:57:28.575688Z",
     "start_time": "2025-10-31T07:57:11.965575Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 测试同时调用 - 时间优先\n",
    "print(\"=== 测试同时调用 - 时间优先 ===\")\n",
    "input_data = {\"input\": \"先告诉我现在几点了，然后再告诉我今天的天气情况\"}\n",
    "print(f\"输入: {input_data['input']}\")\n",
    "result = app.invoke(input_data)\n",
    "print(f\"结果: {result['tool_result']}\\n\")"
   ],
   "id": "a65001f8aca8d8fe",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "=== 测试同时调用 - 时间优先 ===\n",
      "输入: 先告诉我现在几点了，然后再告诉我今天的天气情况\n",
      "LLM决策结果: <think>\n",
      "\n",
      "</think>\n",
      "\n",
      "{\"action\": \"tool_call\", \"tool_calls\": [{\"name\": \"get_current_time\", \"order\": 1}, {\"name\": \"get_weather\", \"order\": 2}]}\n",
      "解析到的JSON: {'action': 'tool_call', 'tool_calls': [{'name': 'get_current_time', 'order': 1}, {'name': 'get_weather', 'order': 2}]}\n",
      "决策函数接收到的输出: tool_call\n",
      "-> 路由到时间工具节点\n",
      "=== 调用时间工具 ===\n",
      "时间工具返回: 当前时间: 2025-10-31 15:57:28\n",
      "工具调用序列: ['get_current_time', 'get_weather']\n",
      "当前索引: 1\n",
      "已完成的工具调用: ['get_current_time']\n",
      "准备调用下一个工具: get_weather\n",
      "-> 路由到天气工具节点\n",
      "=== 调用天气工具 ===\n",
      "天气工具返回: 当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "工具调用序列: ['get_current_time', 'get_weather']\n",
      "当前索引: 2\n",
      "已完成的工具调用: ['get_current_time', 'get_weather']\n",
      "-> 所有工具调用完毕，进入结果聚合\n",
      "=== 聚合工具调用结果 ===\n",
      "聚合结果: 当前时间: 2025-10-31 15:57:28\n",
      "当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "=== 生成最终响应 ===\n",
      "最终响应: 根据您的请求'先告诉我现在几点了，然后再告诉我今天的天气情况'，查询结果如下:\n",
      "当前时间: 2025-10-31 15:57:28\n",
      "当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "结果: 根据您的请求'先告诉我现在几点了，然后再告诉我今天的天气情况'，查询结果如下:\n",
      "当前时间: 2025-10-31 15:57:28\n",
      "当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "\n"
     ]
    }
   ],
   "execution_count": 62
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-31T07:57:44.722170Z",
     "start_time": "2025-10-31T07:57:28.606657Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 测试同时调用 - 天气优先\n",
    "print(\"=== 测试同时调用 - 天气优先 ===\")\n",
    "input_data = {\"input\": \"先告诉我今天的天气情况，然后再告诉我现在几点了\"}\n",
    "print(f\"输入: {input_data['input']}\")\n",
    "result = app.invoke(input_data)\n",
    "print(f\"结果: {result['tool_result']}\\n\")"
   ],
   "id": "79aa833bc48aceb2",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "=== 测试同时调用 - 天气优先 ===\n",
      "输入: 先告诉我今天的天气情况，然后再告诉我现在几点了\n",
      "LLM决策结果: <think>\n",
      "\n",
      "</think>\n",
      "\n",
      "{\"action\": \"tool_call\", \"tool_calls\": [{\"name\": \"get_weather\", \"order\": 1}, {\"name\": \"get_current_time\", \"order\": 2}]}\n",
      "解析到的JSON: {'action': 'tool_call', 'tool_calls': [{'name': 'get_weather', 'order': 1}, {'name': 'get_current_time', 'order': 2}]}\n",
      "决策函数接收到的输出: tool_call\n",
      "-> 路由到天气工具节点\n",
      "=== 调用天气工具 ===\n",
      "天气工具返回: 当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "工具调用序列: ['get_weather', 'get_current_time']\n",
      "当前索引: 1\n",
      "已完成的工具调用: ['get_weather']\n",
      "准备调用下一个工具: get_current_time\n",
      "-> 路由到时间工具节点\n",
      "=== 调用时间工具 ===\n",
      "时间工具返回: 当前时间: 2025-10-31 15:57:44\n",
      "工具调用序列: ['get_weather', 'get_current_time']\n",
      "当前索引: 2\n",
      "已完成的工具调用: ['get_weather', 'get_current_time']\n",
      "-> 所有工具调用完毕，进入结果聚合\n",
      "=== 聚合工具调用结果 ===\n",
      "聚合结果: 当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "当前时间: 2025-10-31 15:57:44\n",
      "=== 生成最终响应 ===\n",
      "最终响应: 根据您的请求'先告诉我今天的天气情况，然后再告诉我现在几点了'，查询结果如下:\n",
      "当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "当前时间: 2025-10-31 15:57:44\n",
      "结果: 根据您的请求'先告诉我今天的天气情况，然后再告诉我现在几点了'，查询结果如下:\n",
      "当前天气: 晴朗，温度 25°C，湿度 60%\n",
      "当前时间: 2025-10-31 15:57:44\n",
      "\n"
     ]
    }
   ],
   "execution_count": 63
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-31T07:57:53.868944Z",
     "start_time": "2025-10-31T07:57:44.731665Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 测试无需工具的情况\n",
    "print(\"=== 测试无需工具 ===\")\n",
    "input_data = {\"input\": \"你好，很高兴认识你\"}\n",
    "print(f\"输入: {input_data['input']}\")\n",
    "result = app.invoke(input_data)\n",
    "print(f\"结果: {result.get('tool_result', '已完成处理')}\\n\")"
   ],
   "id": "828eb7edc4761a6e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "=== 测试无需工具 ===\n",
      "输入: 你好，很高兴认识你\n",
      "LLM决策结果: <think>\n",
      "\n",
      "</think>\n",
      "\n",
      "{\"action\": \"finish\"}\n",
      "解析到的JSON: {'action': 'finish'}\n",
      "决策函数接收到的输出: finish\n",
      "-> 路由到结束节点\n",
      "结果: 已完成处理\n",
      "\n"
     ]
    }
   ],
   "execution_count": 64
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
